#include "uart.h"
#include "board_config.h"
#include "interrupt_controller.h"
#include "ksem.h"

#include "string.h"
#include "timers.h"
#include "cli.h"


#define MAX_BUFFER_LEN 512
//static uint8_t command_buffer[MAX_BUFFER_LEN] __attribute__((section(".os_mem")));
//static uint16_t buf_index __attribute((section(".os_mem")));
static uint8_t command_buffer[MAX_BUFFER_LEN];
static uint16_t buf_index;

cli_cmd_info_t *cli_info_p = NULL;

void uart_print(uint8_t *str)
{
	while (*str != 0)
	{
		uart_put(*str);
		str++;
	}
	return;
}

void uart_interrupt_handler(void)
{
        uint8_t *ptr = NULL;

	// Received a data byte over serial console
	ARM_INTC_SICR = 61;		// Clear interrupt

	if (cli_info_p) {
	    ptr = cli_info_p->cmd_buffer;
	    if (cli_info_p->client_busy) {
	        // Client busy processing previous command
		return;
	    }
	} else {
	    // CLI not yet inited
	    ptr = command_buffer;
	}



	//uart_print((uint8_t *)"Received something\n");

	uint8_t data = UART_RBR;

	if (data >= 32 && data < 127) {
		ptr[buf_index++] = data;
		uart_put(data);
	} else if (data == 8 || data == 127) {
		// backspace
		if (buf_index) {
			buf_index--;
			uart_print((uint8_t *)"\b \b");
		}
	} else if (data == 13) {
		// command complete
		uart_put('\n');

                if (cli_info_p) {
		    ptr[buf_index] = 0;  // complete the current command   
		    unlock_ksem((uint32_t)&cli_info_p->cli_sem);
		    cli_info_p->client_busy = TRUE;
		}

		//@todo: handle this
		// handle only reset command for now
		if (strcmp(ptr, (uint8_t *)"reset") == 0) {
		    reset_processor(0);
		}

		buf_index = 0;
	}


	return;
}


void uart_init(void)
{

	//UART_PEMR = 0x00;	// disable Transmitter and Receiver

	// Set baud rate
	// @todo: Baud rate set by the bootloader is re-used.
	UART_DLL = 0x51;
	UART_DLH = 0x00;
	
	UART_FCR = 0x00;	// Keep in NON-FIFO mode
	UART_FCR = 0x0F;	// Enable DMA, clear RX/TX

	// Set line control
	UART_LCR = 0x03;	// 8 data bits, 1 stop bit, no flow ocntrol
	UART_MCR = 0x00;

	//UART_PEMR = 0x6000;	// Enable the transmitter and receiver

	// Enable receiver interrupt
	UART_IER = 0x01;

	buf_index = 0;
	// Flush out THR
	//UART_THR = 0x00;
	uart_put('\n');
	uart_print((uint8_t *)"UART OPEATIONAL\n");

	return;
}


